package com.kj.misc.service;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.eventbus.Subscribe;
import com.ivan.toolkit.common.Modules;
import com.kj.misc.domain.MiscConfig;
import com.kj.misc.domain.MiscFpaConfig;
import com.kj.misc.domain.MiscStoreType;
import com.kj.misc.domain.MiscValue;

/**
 * 支持多点平均处理
 * @author solod
 */

@Component
public class MiscDataFpa extends Modules{
	
	
	@Autowired
	private MiscData data;
	
	private List<FpaSession> sessions = Lists.newArrayList();
	
	
	public MiscDataFpa() {	
	}

	
	@Override
	public void initialize() {
		
		getConfig().getEntries().forEach(s->{
			FpaSession fs = new FpaSession(s);
			sessions.add(fs);
		});
		
		data.getEventBus().register(this);
	}
	
	@Override
	public void terminate() {
		data.getEventBus().unregister(this);
	}
	

	private MiscFpaConfig getConfig() {
		return MiscConfig.instance.get().getFpaConfig();
	}
	
	
	@Subscribe
	public void dispatchMiscEvent(MiscDataEvent event) {
		
		sessions.forEach(s->{
			s.dispatch(event);
		});
		
	}
	
	public class FpaSession {
		
		private MiscFpaConfig.FpaEntry context;
		
		private List<MiscValue> values = Lists.newLinkedList();

		public FpaSession(MiscFpaConfig.FpaEntry context) {
			super();
			this.context = context;
			
			data.registerData(getKey(), MiscStoreType.period);
		}
		
		public String getKey() {
			return getConfig().getPrefix() + "." + context.getName();
		}
		
		private double feedValue(MiscValue value) {
			
			values.add(value);
			
			int limit = Math.max(context.getFpaCount(), 1);
			
			while(values.size() > limit) {
				values.remove(0);
			}
			
			// 计算平均值
			double avg = values.stream()
                    .collect(Collectors.averagingDouble(MiscValue::getValue));
			
			return avg;
			
		}
		
		public void dispatch(MiscDataEvent event) {
			
			String key = event.getKey();
			
			if(Strings.isNullOrEmpty(key))
				return;
			
			if(key.equals(context.getFpaKey())) {
				
				double value = this.feedValue(event.getNewValue());
				
				data.update(getKey(), value);
				
			} 

		}

	}
	


}
